/**
 * Project: Useful Programs
 * Package: mathematics
 */
package org.leumasjaffe.math;

import java.util.Set;

/**
 * 
 * Class Logic in file Logic.java
 * 
 * @author leumasjaffe
 * Created on: Jul 26, 2012
 *
 */
public abstract class Logic {
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean or(boolean p, boolean q) {
		return p || q;
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean and(boolean p, boolean q) {
		return p && q;
	}
	
	/**
	 * @param p
	 * @return
	 */
	public static boolean not(boolean p) {
		return !p;
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean xor(boolean p, boolean q) {
		return p != q;
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean nor(boolean p, boolean q) {
		return !(p || q);
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean nand(boolean p, boolean q) {
		return !(p && q);
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean implies(boolean p, boolean q) {
		return !p || q;
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean iff(boolean p, boolean q) {
		return p == q;
	}
	
	/**
	 * @param elt
	 * @param set
	 * @return
	 */
	public static <T> boolean elt(T elt, Set<T> set) {
		return set.contains(elt);
	}
	
	/**
	 * @param elt
	 * @param set1
	 * @param set2
	 * @return
	 */
	public static <T> boolean inUnion(T elt, Set<T> set1, Set<T> set2) {
		return elt(elt, set1) || elt(elt, set2);
	}
	
	/**
	 * @param elt
	 * @param set1
	 * @param set2
	 * @return
	 */
	public static <T> boolean inIntersect(T elt, Set<T> set1, Set<T> set2) {
		return elt(elt, set1) && elt(elt, set2);
	}
	
	/**
	 * @param set1
	 * @param set2
	 * @return
	 */
	public static <T> boolean subset(Set<T> set1, Set<T> set2) {
		for (T t : set1)
			if (!set2.contains(t))
				return false;
		return true;
	}
	
	/**
	 * @param set1
	 * @param set2
	 * @return
	 */
	public static <T> boolean superset(Set<T> set1, Set<T> set2) {
		return subset(set2, set1);
	}
	
	/**
	 * @param set1
	 * @param set2
	 * @return
	 */
	public static <T> boolean equal(Set<T> set1, Set<T> set2) {
		return subset(set1, set2) && superset(set1, set2);
	}
	
	/**
	 * @param i
	 * @return
	 */
	public static int bang(int i) {
		return (i == 0 ? 1 : 0);
	}
	
	/**
	 * @param i
	 * @return
	 */
	public static boolean is(int i) {
		return i != 0;
	}
	
	/**
	 * @param i
	 * @return
	 */
	public static boolean not(int i) {
		return i == 0;
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean or(int p, int q) {
		return is(p) || is(q);
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean and(int p, int q) {
		return is(p) && is(q);
	}
		
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean xor(int p, int q) {
		return is(p) != is(q);
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean nor(int p, int q) {
		return not(p) && not(q);
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean nand(int p, int q) {
		return not(p) || not(q);
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean implies(int p, int q) {
		return not(p) || is(q);
	}
	
	/**
	 * @param p
	 * @param q
	 * @return
	 */
	public static boolean iff(int p, int q) {
		return is(p) == is(q);
	}
	
	/**
	 * @param a
	 * @param b
	 * @return
	 */
	public static boolean div(int a, int b) {
		return b%a == 0;
	}
	
	/**
	 * @param n
	 * @return
	 */
	public static boolean even(int n) {
		return div(2, n);
	}
	
	/**
	 * @param n
	 * @return
	 */
	public static boolean odd(int n) {
		return !even(n);
	}

}
